# yun-cha-coffee PyCharm
# 2025/8/30 16:59
# YunCha-Coffee PyCharm
# user 86155
# 2025/8/30 1:15
from datetime import datetime

from fastapi import APIRouter, HTTPException, Query, Depends
from typing import Union, List, Optional, Dict, Any
from tortoise.functions import Sum
from tortoise.contrib.pydantic import pydantic_model_creator

from app.dependencies import get_current_user
from app.models import *
from pydantic import BaseModel, validator, ConfigDict, Field

cartItem_api = APIRouter(prefix="/cart")


# Pydantic 模型
class CartItemPydantic(BaseModel):
    id: int
    user_id: int
    product_id: int
    quantity: int
    added_at: datetime

    model_config = ConfigDict(from_attributes=True)

class CartItemInPydantic(BaseModel):
    product_id: int
    product_type: ProductTypeEnum = Field(default=ProductTypeEnum.COFFEE)
    quantity: int = Field(ge=1, default=1)

    model_config = ConfigDict(from_attributes=True)


# 自定义响应模型


class CartItemCreate(BaseModel):
    user_id: int
    product_id: int
    quantity: int = Field(ge=1, default=1)

class CartItemUpdate(BaseModel):
    quantity: int = Field(ge=1)



class CartItemDetailResponse(BaseModel):
    cart_item: CartItemPydantic
    product_info: dict
    product_type: ProductTypeEnum

    model_config = ConfigDict(from_attributes=True)


@cartItem_api.get("/my/count", summary="获取当前用户购物车商品总数量")
async def get_my_cart_count(current_user: User = Depends(get_current_user)):
    """
    计算当前登录用户购物车中所有商品的数量总和
    - 空购物车返回 0
    - 支持咖啡/周边商品统一计算
    """
    # 用 Sum 聚合函数计算 quantity 总和（高效，无需查询所有商品详情）
    cart_items = await CartItem.filter(user_id=current_user.id).all()
    # 手动累加数量
    total_quantity = sum(item.quantity for item in cart_items)

    return {
        "code": 200,
        "message": "获取购物车数量成功",
        "data": {
            "total_quantity": total_quantity  # 前端直接用这个字段显示数字
        }
    }

@cartItem_api.get("/",summary="查询所有购物车项")
async def getAllCartItems():
    """查询所有购物车记录（可能需要管理员权限）"""
    cart_items = await CartItem.all()

    return {
        "code":200,
        "message": "查询成功",
        "data": cart_items
    }
class CartItemOut(BaseModel):
    id: int
    product_id: int
    product_type: str
    quantity: int
    name: str
    price: float
    img: Optional[str] = None
    added_at: datetime

    class Config:
        orm_mode = True

@cartItem_api.get("/my", response_model=dict,summary="获取当前用户的购物车")
async def get_my_cart(current_user: User = Depends(get_current_user)):
    items = await CartItem.filter(user_id=current_user.id).all()
    data = []
    for ci in items:
        product = await get_product_info(ci.product_id, ci.product_type)
        if not product:
            continue
        data.append(CartItemOut(
            id=ci.id,
            product_id=ci.product_id,
            product_type=ci.product_type,
            quantity=ci.quantity,
            name=product.name,
            price=float(product.price),
            img=product.image_urls[0],
            added_at=ci.added_at
        ))
    return {"code": 200, "message": "成功", "data": data}


@cartItem_api.delete("", summary="删除购物车项")
async def deleteCartItem(ids: List[int] = Query(...,description="购物车项 id 列表"), current_user: User = Depends(get_current_user)):
    """批量删除购物车项"""
    deleted = await CartItem.filter(id__in=ids, user_id=current_user.id).delete()

    if not deleted:
        raise HTTPException(404, "未找到可删除项")
    return {
        "code": 200,
        "message": f"成功删除 {deleted} 个购物车项",
        "data": None
    }




class ProductInfo(BaseModel):
    id: int
    name: str
    price: float


    model_config = ConfigDict(from_attributes=True)


async def get_product_info(product_id: int, product_type: ProductTypeEnum) -> ProductInfo:
    if product_type == ProductTypeEnum.COFFEE:
        return await CoffeeProduct.get_or_none(id=product_id)
    elif product_type == ProductTypeEnum.MERCHANDISE:
        return await MerchandiseProduct.get_or_none(id=product_id)
    return None




@cartItem_api.get("/{cart_item_id}", summary="查询购物车项详情")
async def getOneCertitemdetail(cart_item_id: int, user_id: int):
    """获取购物车项的详细信息"""
    cart_item = await CartItem.filter(id=cart_item_id, user_id=user_id).first()

    if not cart_item:
        raise HTTPException(status_code=404, detail="购物车项不存在")

        # 确保 product_type 是有效的枚举值
    if not isinstance(cart_item.product_type, ProductTypeEnum):
        try:
            cart_item.product_type = ProductTypeEnum(cart_item.product_type or "coffee")
        except ValueError:
            cart_item.product_type = ProductTypeEnum.COFFEE

    # 获取商品详细信息
    product_info = await get_product_info(cart_item.product_id,cart_item.product_type)
    # 手动构建 cart_item 数据
    cart_item_data = {
        "id": cart_item.id,
        "user_id": cart_item.user_id,
        "product_id": cart_item.product_id,
        "quantity": cart_item.quantity

    }

    return {
        "message": "查询成功",
        "data": {
            "cart_item": cart_item_data,
            "product_info": product_info
        }
    }



@cartItem_api.post("", summary="添加商品到购物车")
async def add_to_cart(
    payload: CartItemInPydantic,
    current_user: User = Depends(get_current_user)
):
    print(f"当前登录用户 ID: {current_user.id}")
    # 选表
    model_map = {
        ProductTypeEnum.COFFEE: CoffeeProduct,
        ProductTypeEnum.MERCHANDISE: MerchandiseProduct
    }
    product_model = model_map[payload.product_type]

    product = await product_model.get_or_none(id=payload.product_id)
    if not product:
        raise HTTPException(404, "商品不存在")

    # 库存校验
    if hasattr(product, 'stock') and product.stock < payload.quantity:
        raise HTTPException(400, "库存不足")

    # 已存在则累加
    ci, created = await CartItem.get_or_create(
        user_id=current_user.id,
        product_id=payload.product_id,
        product_type=payload.product_type,
        defaults={"quantity": payload.quantity}
    )
    if not created:
        new_qty = ci.quantity + payload.quantity
        if hasattr(product, 'stock') and new_qty > product.stock:
            raise HTTPException(400, "库存不足")
        ci.quantity = new_qty
        await ci.save()

    return {"code": 200, "message": "已加入购物车", "data": None}



class CartItemUpdatePydantic(BaseModel):
    quantity: int = Field(gt=0, description="商品数量必须大于0")

class CartBatchIn(BaseModel):
    items: List[dict]   # [{id:int, qty:int}]

@cartItem_api.put("/batch", summary="批量更新购物车数量")
async def update_cart_batch(
    body: CartBatchIn,
    current_user: User = Depends(get_current_user)
):
    # 1. 先验证这些购物车项都属于当前用户
    cart_ids = [it["id"] for it in body.items]
    db_items = await CartItem.filter(id__in=cart_ids, user_id=current_user.id).all()
    if len(db_items) != len(cart_ids):
        raise HTTPException(404, "存在不属于自己的购物车项")

    # 2. 逐个更新数量
    for it in body.items:
        await CartItem.filter(id=it["id"]).update(quantity=it["qty"])
    return {"code": 200, "message": "已保存", "data": None}

